//超声波模块
/* 硬件
	电路板上有4个引脚：

	VCC（正级）
	Trig（触发）
	Echo（回应）
	GND（接地-负极）
*/

/* s = v*t  计算出超声波
51单片机 1个机器周期是12个时钟周期， 时钟周期=1/（时钟源频率）
所以一个机器周期时间就是12/11.0592MHz = 12/11059200s，一个机器周期定时器计数加一
所以用超声波模块计时时间 t = (TH0*256+TL0)*12/11.0595/1000/1000
由于这个计数时间是双程距离（来回），所以时间要/2  t = (TH0*256+TL0)*12/11.0595/1000/1000/2
声速340m/s ，s = v*t 单位是m，最后乘以100 单位化成cm
将后面计算简化得0.01844618

	(TH0*256+TL0)*12/11.0595/1000/1000/2*340*100  (cm)
   =(TH0*256+TL0)*1.085/58
   =(TH0*256+TL0)*0.01844618
*/



#include <REGX52.H>
#include "Ultrasonic.h"
#include "intrins.h"
#include "Delay.h"

//sbit Trig = P2^2;	//超声波测距发射端位点
//sbit Echo = P2^1;	//超声波测距接收端位点


sbit Trig = P2^7;	//超声波测距发射端位点
sbit Echo = P2^6;	//超声波测距接收端位点

void Delay50us()		//@11.0592MHz, trig 高于10us高电平，超声波专用延时函数
{		
	unsigned char i;

	_nop_();
	i = 20;
	while (--i);
}



void Timer0_Init(void)	//不需要中断
{	
	TMOD &= 0xF0;		
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x00;		
	TH0 = 0x00;				
	TR0 = 0;				
}

void ultrasonic_init(void)
{
	Timer0_Init();
	Trig = 0;
	Echo = 1;
	
}

int Ultrasonic(void)
{
	int juli=0;	//返回值
	int temp_buf[11];	//数据缓冲区
	int ftemp;	//暂存距离 变量
	int temp_sum = 0;
	unsigned char i = 0, j = 0;		//循环变量
	
	for(i=0;i<10;i++)	//测量十次，冒泡排序，取出六次中间平均值
	{
		Trig = 1;		//发射50us高电平
		Delay50us();
		Trig = 0;
		
		while(!Echo);	//等待超声波模块的返回脉冲(等待高电平)
		TL0 = 0x00;		
		TH0 = 0x00;		//清零计数器数值
		TR0 = 1;		//开启定时器
		while(Echo);	//等待超声波模块的返回脉冲结束(等待高电平结束)
		TR0 = 0;		//停止定时器，计时结束
		temp_buf[i] = (TH0*256+TL0)*0.018446;		//0.018446这个数据上边有解释
		Delay(1);		//延时1ms
	}
	
	
	
	
//冒泡排序法，升序排序，滤波处理，消除干扰数据
	for(i=0;i<9;i++)	//10个数据，进行9次
	{
		for(j=i+1;j<10;j++)	//大的数据，依次往后冒泡
		{
			if(temp_buf[i] > temp_buf[j])
			{
				ftemp = temp_buf[i];
				temp_buf[i] = temp_buf[j];
				temp_buf[j] = ftemp;
			}
		}
	}
	
	
	for(i=2;i<8;i++)	//对中间六个数据取平均值	
		temp_sum += temp_buf[i];
	
	juli = temp_sum/6;
	
	return juli;
}
	

